#include "base.h"
#include "intr.h"
#include "syscall.h"
#include "proc.h"
#include "page.h"
#include "string.h"

PUBLIC struct syscall_handler_t sys_call_table[] ={
	{SYS_CUR_PROC,			do_cur_proc	},
	{SYS_FORK,				do_fork		},
	{SYS_KILL,				do_kill		},
	{SYS_SUSPEND,			do_suspend	},
	{SYS_READ,				do_read		},
	{SYS_WRITE,				do_write		},
	{SYS_MALLOC,				do_malloc		},
	{SYS_FREE,				do_free		},

	/* end */
	{SYS_INVALID,			NULL		}

};


int do_cur_proc(struct syscall_t *sys){
	/* avoid warning */
	sys = sys;

	return cur_proc->pid;
}

int do_fork(struct syscall_t *sys){
	struct proc *new_proc;

	/* avoid warning */
	sys = sys;

	if ((new_proc = proc_new())){
		uint_32 phy;
		
		new_proc->priv = cur_proc->priv;
		new_proc->ticks = DEFAULT_TICK;
		new_proc->sleep_ticks = DEFAULT_TICK;
		new_proc->status = READY;
#if 0
		new_proc->father = cur_proc;
#endif
		/* alloc the physical page */
		if (page_alloc(&phy)){
			/* alloc failed */
		}

		new_proc->mm.start_phy = phy;
		new_proc->mm.start_vm = cur_proc->mm.start_vm;
		
		page_map(&(new_proc->mm));

		/* same context with father */
		memcpy((char *)(&(new_proc->context)),
			(char *)(&(cur_proc->context)),sizeof(struct task_context));

#if 0
		proc_enbrotherq(cur_proc,new_proc);
#endif

		/*enqueue the schedule queue */
		proc_en_ready_queue(new_proc);
	}
	return 0;
}

int do_kill(struct syscall_t *sys){
#if 0
	struct proc *child = cur_proc->child;

	uint_32 to_kill_pid = sys->p1;
	
	for ( ;child; child = child->brother){
		if (to_kill_pid == child->pid){
			break;
		}
	}

	if (!child){
		return 1;
	}

	proc_free(&child);
	return 0;
#endif
	return 0;
}

int do_suspend(struct syscall_t *sys){
	/* avoid warning */
	sys = sys;
	
	cur_proc->status = SUSPEND;
	proc_de_ready_queue(cur_proc);
	proc_en_suspend_queue(cur_proc);

	/* make cur_proc point to null process */
	cur_proc = NULL;
	return 0;
}

int do_exit(struct syscall_t *sys){
	/* avoid warning */
	sys = sys;
	
	proc_free(&cur_proc);
	return 0;
}

int do_exec(struct syscall_t *sys){
	return 0;
}

int do_timer(struct syscall_t *sys){
	return 0;
}

int do_sleep(struct syscall_t *sys){
	uint_32 sleep_timer = sys->p1;
	cur_proc->status = SUSPEND;
	cur_proc->sleep_ticks= sleep_timer / 10;
	proc_de_ready_queue(cur_proc);
	proc_en_suspend_queue(cur_proc);

	/* make cur_proc point to null process */
	cur_proc = NULL;
	return 0;
}

int do_read(struct syscall_t *sys){
	return 0;
}

int do_write(struct syscall_t *sys){
	return 0;
}

int do_new_mem(struct syscall_t *sys){
	return 0;
}

int do_malloc(struct syscall_t *sys){
	return 0;
}

int do_free(struct syscall_t *sys){
	return 0;
}

int do_print(struct syscall_t *sys){
	return 0;
}

